package com.zjcloud.jwgl.service.impl;

import java.util.List;
import java.util.ArrayList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.zjcloud.common.utils.DateUtils;
import com.zjcloud.common.utils.SecurityUtils;
import com.zjcloud.jwgl.mapper.AcScheduleConstraintTemplateMapper;
import com.zjcloud.jwgl.mapper.AcScheduleConstraintMapper;
import com.zjcloud.jwgl.domain.AcScheduleConstraintTemplate;
import com.zjcloud.jwgl.domain.AcScheduleConstraint;
import com.zjcloud.jwgl.service.IAcScheduleConstraintTemplateService;
import com.zjcloud.jwgl.service.IAcTemplateAggregateService;
import com.zjcloud.jwgl.exception.TemplateValidationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

/**
 * 排课约束条件模板Service业务层处理
 * 
 * @author zjcloud
 * @date 2024-12-19
 */
@Service
public class AcScheduleConstraintTemplateServiceImpl implements IAcScheduleConstraintTemplateService 
{
    private static final Logger log = LoggerFactory.getLogger(AcScheduleConstraintTemplateServiceImpl.class);
    
    @Autowired
    private AcScheduleConstraintTemplateMapper acScheduleConstraintTemplateMapper;
    
    @Autowired
    private AcScheduleConstraintMapper acScheduleConstraintMapper;
    
    @Autowired
    private IAcTemplateAggregateService templateAggregateService;

    /**
     * 查询排课约束条件模板
     * 
     * @param id 排课约束条件模板主键
     * @return 排课约束条件模板
     */
    @Override
    public AcScheduleConstraintTemplate selectAcScheduleConstraintTemplateById(Long id)
    {
        return acScheduleConstraintTemplateMapper.selectAcScheduleConstraintTemplateById(id);
    }

    /**
     * 查询排课约束条件模板列表
     * 
     * @param acScheduleConstraintTemplate 排课约束条件模板
     * @return 排课约束条件模板
     */
    @Override
    public List<AcScheduleConstraintTemplate> selectAcScheduleConstraintTemplateList(AcScheduleConstraintTemplate acScheduleConstraintTemplate)
    {
        return acScheduleConstraintTemplateMapper.selectAcScheduleConstraintTemplateList(acScheduleConstraintTemplate);
    }

    /**
     * 新增排课约束条件模板
     * 
     * @param acScheduleConstraintTemplate 排课约束条件模板
     * @return 结果
     */
    @Override
    public int insertAcScheduleConstraintTemplate(AcScheduleConstraintTemplate acScheduleConstraintTemplate)
    {
        acScheduleConstraintTemplate.setCreateTime(DateUtils.getNowDate());
        acScheduleConstraintTemplate.setCreateBy(SecurityUtils.getUsername());
        return acScheduleConstraintTemplateMapper.insertAcScheduleConstraintTemplate(acScheduleConstraintTemplate);
    }

    /**
     * 修改排课约束条件模板
     * 
     * @param acScheduleConstraintTemplate 排课约束条件模板
     * @return 结果
     */
    @Override
    public int updateAcScheduleConstraintTemplate(AcScheduleConstraintTemplate acScheduleConstraintTemplate)
    {
        acScheduleConstraintTemplate.setUpdateTime(DateUtils.getNowDate());
        acScheduleConstraintTemplate.setUpdateBy(SecurityUtils.getUsername());
        return acScheduleConstraintTemplateMapper.updateAcScheduleConstraintTemplate(acScheduleConstraintTemplate);
    }

    /**
     * 批量删除排课约束条件模板
     * 
     * @param ids 需要删除的排课约束条件模板主键
     * @return 结果
     */
    @Override
    public int deleteAcScheduleConstraintTemplateByIds(Long[] ids)
    {
        return acScheduleConstraintTemplateMapper.deleteAcScheduleConstraintTemplateByIds(ids);
    }

    /**
     * 删除排课约束条件模板信息
     * 
     * @param id 排课约束条件模板主键
     * @return 结果
     */
    @Override
    public int deleteAcScheduleConstraintTemplateById(Long id)
    {
        return acScheduleConstraintTemplateMapper.deleteAcScheduleConstraintTemplateById(id);
    }

    /**
     * 查询默认模板列表
     * 
     * @return 默认模板集合
     */
    @Override
    public List<AcScheduleConstraintTemplate> selectDefaultTemplates()
    {
        return acScheduleConstraintTemplateMapper.selectDefaultTemplates();
    }

    /**
     * 根据模板名称查询模板列表
     * 
     * @param templateName 模板名称
     * @return 模板信息列表
     */
    @Override
    public List<AcScheduleConstraintTemplate> selectByTemplateName(String templateName)
    {
        return acScheduleConstraintTemplateMapper.selectByTemplateName(templateName);
    }

    /**
     * 根据模板名称查询第一个模板（向后兼容）
     * 
     * @param templateName 模板名称
     * @return 模板信息
     */
    @Override
    public AcScheduleConstraintTemplate selectFirstByTemplateName(String templateName)
    {
        List<AcScheduleConstraintTemplate> templates = acScheduleConstraintTemplateMapper.selectByTemplateName(templateName);
        return templates != null && !templates.isEmpty() ? templates.get(0) : null;
    }

    /**
     * 设置默认模板
     * 
     * @param id 模板ID
     * @return 结果
     */
    @Override
    @Transactional
    public int setDefaultTemplate(Long id)
    {
        // 先清除所有默认模板标记
        acScheduleConstraintTemplateMapper.clearDefaultTemplates();
        // 设置新的默认模板
        return acScheduleConstraintTemplateMapper.setDefaultTemplate(id);
    }

    /**
     * 根据模板初始化约束条件数据
     * 
     * @param templateName 模板名称
     * @param semester 学期
     * @return 初始化的约束条件列表
     */
    @Override
    public List<AcScheduleConstraint> initConstraintsBySemester(String templateName, String semester)
    {
        List<AcScheduleConstraint> constraints = new ArrayList<>();
        
        // 查询模板数据
        AcScheduleConstraintTemplate queryTemplate = new AcScheduleConstraintTemplate();
        if (templateName != null && !templateName.isEmpty()) {
            queryTemplate.setTemplateName(templateName);
        } else {
            queryTemplate.setIsDefault("1");
        }
        queryTemplate.setEnabled("1");
        
        List<AcScheduleConstraintTemplate> templates = acScheduleConstraintTemplateMapper.selectAcScheduleConstraintTemplateList(queryTemplate);
        
        // 根据模板创建约束条件
        for (AcScheduleConstraintTemplate template : templates) {
            AcScheduleConstraint constraint = new AcScheduleConstraint();
            constraint.setName(template.getConstraintName());
            // 需要根据约束类型名称查找对应的约束类型ID
            // 这里暂时设置为1，实际应该根据template.getConstraintType()查找对应的ID
            constraint.setConstraintTypeId(1L);
            constraint.setWeight(template.getDefaultWeight());
            constraint.setEnabled(template.getEnabled());
            constraint.setSemester(semester);
            constraint.setCreateBy(SecurityUtils.getUsername());
            constraint.setCreateTime(DateUtils.getNowDate());
            constraints.add(constraint);
        }
        
        return constraints;
    }

    /**
     * 应用默认模板到指定学期
     * 
     * @param semester 学期
     * @return 结果
     */
    @Override
    @Transactional
    public int applyDefaultTemplate(String semester)
    {
        // 获取默认模板数据
        List<AcScheduleConstraint> constraints = initConstraintsBySemester(null, semester);
        
        if (constraints.isEmpty()) {
            return 0;
        }
        
        int successCount = 0;
        
        // 删除该学期现有的约束条件
        AcScheduleConstraint deleteQuery = new AcScheduleConstraint();
        deleteQuery.setSemester(semester);
        List<AcScheduleConstraint> existingConstraints = acScheduleConstraintMapper.selectAcScheduleConstraintList(deleteQuery);
        if (!existingConstraints.isEmpty()) {
            Long[] ids = existingConstraints.stream().map(AcScheduleConstraint::getId).toArray(Long[]::new);
            acScheduleConstraintMapper.deleteAcScheduleConstraintByIds(ids);
        }
        
        // 插入新的约束条件
        for (AcScheduleConstraint constraint : constraints) {
            int result = acScheduleConstraintMapper.insertAcScheduleConstraint(constraint);
            if (result > 0) {
                successCount++;
            }
        }
        
        return successCount;
    }

    /**
     * 复制模板
     * 
     * @param sourceId 源模板ID
     * @param newTemplateName 新模板名称
     * @return 结果
     */
    @Override
    public int copyTemplate(Long sourceId, String newTemplateName)
    {
        // 查询源模板
        AcScheduleConstraintTemplate sourceTemplate = acScheduleConstraintTemplateMapper.selectAcScheduleConstraintTemplateById(sourceId);
        if (sourceTemplate == null) {
            return 0;
        }
        
        // 创建新模板
        AcScheduleConstraintTemplate newTemplate = new AcScheduleConstraintTemplate();
        newTemplate.setTemplateName(newTemplateName);
        newTemplate.setDescription("复制自: " + sourceTemplate.getTemplateName());
        newTemplate.setConstraintName(sourceTemplate.getConstraintName());
        newTemplate.setConstraintType(sourceTemplate.getConstraintType());
        newTemplate.setDefaultWeight(sourceTemplate.getDefaultWeight());
        newTemplate.setEnabled(sourceTemplate.getEnabled());
        newTemplate.setIsDefault("0"); // 复制的模板默认不是系统默认
        newTemplate.setSortOrder(sourceTemplate.getSortOrder());
        newTemplate.setCreateBy(SecurityUtils.getUsername());
        newTemplate.setCreateTime(DateUtils.getNowDate());
        
        return acScheduleConstraintTemplateMapper.insertAcScheduleConstraintTemplate(newTemplate);
    }

    /**
     * 根据模板名称初始化约束条件（修复版本）
     * 使用聚合服务确保模板完整性
     * 
     * @param templateName 模板名称
     * @param semester 学期
     * @return 初始化的约束条件列表
     * @throws TemplateValidationException 当模板验证失败时抛出异常
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<AcScheduleConstraint> initFromTemplate(String templateName, String semester) throws TemplateValidationException
    {
        log.info("开始根据模板 {} 初始化学期 {} 的约束条件", templateName, semester);
        
        // 参数验证
        if (!StringUtils.hasText(templateName)) {
            throw new TemplateValidationException("INVALID_TEMPLATE_NAME", "模板名称不能为空", templateName);
        }
        
        if (!StringUtils.hasText(semester)) {
            throw new TemplateValidationException("INVALID_SEMESTER", "学期不能为空", templateName);
        }
        
        try {
            // 使用聚合服务获取完整的模板信息（包含完整性验证）
            List<AcScheduleConstraintTemplate> templates = templateAggregateService.getCompleteTemplate(templateName);
            
            if (templates.isEmpty()) {
                throw new TemplateValidationException("TEMPLATE_EMPTY", "模板数据为空", templateName);
            }
            
            List<AcScheduleConstraint> constraints = new ArrayList<>();
            String currentUser = SecurityUtils.getUsername();
            
            // 根据模板创建约束条件
            for (AcScheduleConstraintTemplate template : templates) {
                AcScheduleConstraint constraint = new AcScheduleConstraint();
                constraint.setName(template.getConstraintName());
                // 需要根据约束类型名称查找对应的约束类型ID
                // 这里暂时设置为1，实际应该根据template.getConstraintType()查找对应的ID
                constraint.setConstraintTypeId(1L);
                constraint.setWeight(template.getDefaultWeight());
                constraint.setEnabled(template.getEnabled());
                constraint.setSemester(semester);
                constraint.setCreateBy(currentUser);
                constraint.setCreateTime(DateUtils.getNowDate());
                constraints.add(constraint);
            }
            
            log.info("成功根据模板 {} 创建了 {} 个约束条件", templateName, constraints.size());
            return constraints;
            
        } catch (TemplateValidationException e) {
            log.error("模板验证失败: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("初始化约束条件时发生未知错误: {}", e.getMessage(), e);
            throw new TemplateValidationException("INIT_ERROR", "初始化约束条件失败: " + e.getMessage(), templateName);
        }
    }
}